﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace odinshrine
{
    class Soldat:BadGuys
    {
        public LinkedList<LinkedList<Structure>> pathsList = new LinkedList<LinkedList<Structure>>();
        private LinkedList<Structure> strucFoundList = new LinkedList<Structure>();
        private Structure targetStruct;
        private LinkedList<Structure> cheminCourt = new LinkedList<Structure>();
        public int X = 0, Y = 0;

        public void findStruct(Joueur player, map Map, BadGuys ennemi, int depLarg, int depHaut)
        {
             X = (int)((player.Position.X - player.width) + Map.coefx) / 34 + 1 ;
             Y = (int)(player.Position.Y + player.height) / 34;
             
             try
             {
                 if (Map.caisseList2[X, Y] != null)
                 {
                     
                     strucFoundList.AddLast(Map.structlist[Map.caisseList2[X, Y].structIndic]);
                     findPath(Map.structlist[Map.caisseList2[X, Y].structIndic], strucFoundList, ennemi, Map, depLarg, depHaut);
                 }
             }
             catch { }
        }

        private bool eltProcheEnd(Structure struc, map Map, LinkedList<Structure> l, int depLarg, int depHaut)
        {
            //Parcours des cases autour du joueur
            for (int i = (int)(struc.end.Pos.X - depLarg + Map.coefx) / 34; i < Map.caisseList2.GetLength(0) && i < (struc.end.Pos.X + Map.coefx - depLarg) / 34 + depLarg / 17; i++)
            {
                for(int j = (int)(struc.end.Pos.Y - depHaut)/34;j < Map.caisseList2.GetLength(1) && j<(struc.end.Pos.Y - depHaut)/34 + depHaut/17; j++)
                {
                    if (Map.caisseList2[i, j] != null)
                    {
                        if (!l.Contains(Map.structlist[Map.caisseList2[i, j].structIndic]))
                        {
                            targetStruct = Map.structlist[Map.caisseList2[i, j].structIndic];
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        private bool eltProcheBeg(Structure struc, map Map, LinkedList<Structure> l, int depLarg, int depHaut)
        {
            //Parcours des cases autour du joueur
            for (int i = (int)(struc.beg.Pos.X - depLarg + Map.coefx) / 34; i < Map.caisseList2.GetLength(0) && i < (struc.beg.Pos.X + Map.coefx - depLarg) / 34 + depLarg / 17; i++)
            {
                for (int j = (int)(struc.beg.Pos.Y - depHaut) / 34; j < Map.caisseList2.GetLength(1) && j < (struc.beg.Pos.Y - depHaut) / 34 + depHaut / 17; j++)
                {
                    if (Map.caisseList2[i, j] != null)
                    {
                        if (!l.Contains(Map.structlist[Map.caisseList2[i, j].structIndic]))
                        {
                            targetStruct = Map.structlist[Map.caisseList2[i, j].structIndic];
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        public LinkedList<Structure> pathEvaluation()
        {
            int accu = 0;
            LinkedList<Structure> min = new LinkedList<Structure>();
            LinkedList<Structure>[] tab = new LinkedList<Structure>[pathsList.Count];
            //On met la liste en statique
            foreach (LinkedList<Structure> l in pathsList)
            {
                tab[accu] = l;
                accu++;
            }
            min = tab[0];
            int i = 0;
            while(i<tab.GetLength(0))
            {
                if (tab[i].Count <= min.Count)
                {
                    min = tab[i];
                }
                i++;
            }
            return min;
        }

        private bool ennemiProcheEnd(Structure struc, BadGuys ennemi, int depLarg, int depHaut)
        {
            GestionPhysics phys = new GestionPhysics();
            return phys.collisionRectangleRectangle(new Rectangle((int)struc.end.Pos.X + 34, (int)struc.end.Pos.Y + 34, depLarg, depHaut),
                new Rectangle((int)ennemi.Position.X - ennemi.width, (int)ennemi.Position.Y + ennemi.height, depLarg, depHaut));
        }

        private bool ennemiProcheBeg(Structure struc, BadGuys ennemi, int depLarg, int depHaut)
        {
            GestionPhysics phys = new GestionPhysics();
            return phys.collisionRectangleRectangle(new Rectangle((int)struc.beg.Pos.X, (int)struc.beg.Pos.Y, depLarg, depHaut),
                new Rectangle((int)ennemi.Position.X - ennemi.width, (int)ennemi.Position.Y + ennemi.height, depLarg, depHaut));
        }

        public void findPath(Structure strucFound, LinkedList<Structure> list, BadGuys ennemi, map Map, int depLargeur, int depHauteur)
        {
            LinkedList<Structure> newlistb = new LinkedList<Structure>(list);
            LinkedList<Structure> newliste = new LinkedList<Structure>(list);

            if (ennemiProcheEnd(strucFound, ennemi, depLargeur, depHauteur))
            {
                pathsList.AddLast(list);
            }
            if (eltProcheEnd(strucFound, Map, newliste, depLargeur, depHauteur))
            {
                newliste.AddFirst(targetStruct);
                findPath(targetStruct, newliste, ennemi, Map, depLargeur, depHauteur);
            }

            if (ennemiProcheBeg(strucFound, ennemi, depLargeur, depHauteur))
            {
                pathsList.AddLast(list);
            }
            if(eltProcheBeg(strucFound, Map, newlistb, depLargeur, depHauteur))
            {
                newlistb.AddFirst(targetStruct);
                findPath(targetStruct, newlistb, ennemi, Map, depLargeur, depHauteur);
            }

        }
        public Soldat(ContentManager Content)
            : base(Content.Load<Texture2D>("Images/ennemi2"), 1, 1, 20, 7, Armerie.Pompe, 50)
        {

        }
    }
}
